package binpacking.algorithms;

import java.util.List;

import binpacking.model.*;

public class WorstFit {
	private List<Block> blocks;
	private BinContainer binContainer;
	private int binSize;
	
	public WorstFit( List<Block> l, BinContainer binContainer, int binSize ) {
		this.blocks = l;
		this.binContainer = binContainer;
		this.binSize = binSize;
	}
	
	public void doWorstFit() {
		
		// alle blokken moeten in een bin worden gestopt
		while(blocks.size() > 0) {
			
			// haal het voorste blok uit de lijst en verwijder deze uit de lijst
			Block block = blocks.remove(0);
			
			// voor elk blok wordt de bin index weer op 0 gezet om alle bins door te lopen
			int binIndex = 0;
			
			// minSpace op te groot zetten
			// eneen binindex bij houden voor de bin met de minste ruimte
			int maxSpace = -1;
			int chosenBinIndex = 0;
			// alle al Worstaande bins doorlopen
			while( binIndex < binContainer.getBins().size() ){				
				Bin bin = binContainer.getBins().get( binIndex );
				// als er ruimte in de bin is
				if( bin.storageAvailable( block.getSize() ) ){
					// en de ruimte na plaatsing is de grootste tot nu toe
					if( bin.getStorageRemaining( block.getSize() ) > maxSpace ){
						// bin en space opslaan
						maxSpace = bin.getStorageRemaining( block.getSize() );
						chosenBinIndex = binIndex;
					}
				}
				binIndex++;
			}
			// als er een minspace is gevonden, dus het blok is in een bin te plaatsen
			if( maxSpace >= (0) ){
				// plaats het blok in de bin met de minste ruimte na plaatsing
				binContainer.getBins().get( chosenBinIndex ).addBlock( block );
				block.place();
				binIndex = 0;
				
			} else {
				// anders past de het blok niet in de huidige bins en moet er een nieuwe worden aangemaakt
				Bin bin = new Bin(binSize);
				bin.addBlock( block );
				block.place();
				binContainer.addBin( bin );
			}
		}
	}
	
	public void doWorstFitDecreasing() {
		doWorstFit(); 
	}
	
	public String getResult() {
		return "Bins used: " + binContainer.getBins().size() + "\n" + binContainer.getVisualRepresentation();
	}
}
